Skip to content

feat: oss index groups endpoint - #2350

Merged
epipav merged 5 commits into
mainfrom
feat/IN-1414
Oct 14, 2026
Merged

epipav merged 5 commits into
mainfrom
feat/IN-1414

Conversation

@epipav

@epipav epipav commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Adds GET /v1-alpha/oss-index/groups (IN-1414, epic IN-1146). It returns the OSS Index category groups with their top collections and top projects.

  • api/src/lib/oss-index.ts holds the shared pieces for the OSS Index routes: guards and mappers that turn the pipe's positional topCollections and topProjects tuples into named objects, their schemas, and the sort query param.
  • oss-index/groups.ts reads category_groups_oss_index. type filters the groups and sort (totalContributors or softwareValue, default totalContributors) orders them.
  • Project tuples map their logo slot to logoUrl, and their v2 health fields to healthScore, healthLabel and healthMaxScore, as the collection projects endpoint does. The pipe's v1 score is left out.
  • isHealthScore in src/lib/overview.ts holds the v2 health check, now shared with src/lib/collections.ts.
  • A malformed row or tuple answers 503 upstream_unavailable. An invalid sort answers 400.

Notes

  • Tuple slots are non-nullable apart from the four v2 health fields that end a project tuple, so any other null counts as a malformed row.
  • The response is { data: [...] }, matching the leaderboards routes.
  • The categories and collections endpoints stack on this branch and reuse the shared module.

Tests

  • tests/oss-index.test.ts: tuple guards and mappers.
  • tests/oss-index-groups.test.ts: response shape, sort and type forwarding, 400 for an invalid sort, 503 for malformed rows, empty list, and the OpenAPI entry.

Copilot AI balanced review requested due to automatic review settings October 1, 2026 13:03
@cursor

cursor Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

PR Summary

Low Risk
Read-only new endpoint with strict upstream validation; shared health validation refactor is covered by existing and new tests.

Overview
Adds GET /v1-alpha/oss-index/groups, which returns OSS Index category groups (totals, leading collections, leading projects) from the category_groups_oss_index Tinybird pipe. Optional type filters group kind; sort (totalContributors or softwareValue) is passed through as orderBy. Malformed pipe rows answer 503; invalid sort answers 400.

Introduces api/src/lib/oss-index.ts for pipe tuple validation, OpenAPI schemas, and mappers that turn positional topCollections / topProjects tuples into named objects (including v2 healthScore, healthLabel, healthMaxScore on projects, dropping the v1 score).

isHealthScore moves into overview.ts and replaces duplicated health-field checks in collections.ts, with added tests for inconsistent health triples and repo rows that have a score but no maximum.

Reviewed by Cursor Bugbot for commit 0f77152. Bugbot is set up for automated code reviews on this repo. Configure here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Numeric guards currently accept counts and scores that violate the documented response contract.

Review effort: Balanced
Findings: 2 Medium severity

Open (2)
What changed in this PR

Adds the OSS Index category groups API with validated tuple mapping and Tinybird integration.

Changes:

  • Adds GET /v1-alpha/oss-index/groups.
  • Introduces shared OSS Index schemas, guards, and mappers.
  • Adds unit and integration coverage.
File Description
api/​src/​lib/​oss-index.ts Defines shared tuple guards, mappers, schemas, and sorting.
api/​src/​versions/​v1-alpha/​oss-index/​groups.ts Implements the groups endpoint.
api/​tests/​oss-index.test.ts Tests tuple validation and mapping.
api/​tests/​oss-index-groups.test.ts Tests routing, filtering, errors, and OpenAPI registration.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread api/src/lib/oss-index.ts
Comment thread api/src/versions/v1-alpha/oss-index/groups.ts Outdated
@epipav epipav self-assigned this Oct 1, 2026
@epipav epipav assigned themarolt and unassigned themarolt Oct 1, 2026
@epipav
epipav requested review from gaspergrom and themarolt and a balanced review from Copilot October 1, 2026 13:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Score guards accept values outside documented ranges, allowing malformed upstream data to return 200 instead of 503.

Review effort: Balanced
Findings: None

Resolved since last review (2)
Previously missed (1)

In code that hasn't changed since last review

Low severity Use “accepts” for grammatical consistency

api/​tests/​oss-index.test.ts:54

Use “accepts” so this test description is grammatically consistent with the surrounding it(...) cases.

@gaspergrom gaspergrom left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. The tuple guards and slot mapping match the pipe's column order, and the sort and type params line up with what the pipe accepts.

@themarolt themarolt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good - one question on projectCount, if the pipe doesn't send it every row fails the guard

Comment thread api/src/versions/v1-alpha/oss-index/groups.ts
@epipav
epipav added this pull request to stack #2380 October 14, 2026 11:23
Signed-off-by: anilb <epipav@gmail.com>
Signed-off-by: anilb <epipav@gmail.com>
Copilot AI balanced review requested due to automatic review settings October 14, 2026 11:27

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread api/src/lib/oss-index.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The project tuple guard rejects the existing 13-slot upstream shape, causing valid requests to return 503, and score bounds are not enforced.

1 open finding

🧠 Review effort: Balanced

Comment thread api/src/lib/oss-index.ts Outdated
Signed-off-by: anilb <epipav@gmail.com>
Copilot AI balanced review requested due to automatic review settings October 14, 2026 12:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Score guards currently accept values outside their documented ranges, bypassing malformed-upstream handling.

1 open finding
1 resolved since last review

🧠 Review effort: Balanced

Comment thread api/tests/oss-index.test.ts Outdated
Signed-off-by: anilb <epipav@gmail.com>
Copilot AI balanced review requested due to automatic review settings October 14, 2026 12:49
@epipav

epipav commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

@cursor review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Guards currently accept invalid score combinations and averages outside the documented range.

1 open finding
1 resolved since last review
Previously missed (2)

In code that hasn't changed since last review

Low severity Add 0–1 bounds to the generated OpenAPI schema

api/​src/​lib/​oss-index.ts:70

The generated OpenAPI schema does not encode the stated 0–1 constraint, although bounded numeric responses elsewhere use minimum/maximum (for example collections/metrics.ts:37-43). Add the bounds so generated clients and validators receive the actual contract.

This issue also appears on line 84 of the same file.

Low severity Expose average bounds in the public OpenAPI schema

api/​src/​versions/​v1-alpha/​oss-index/​groups.ts:70

The public schema states that this average is 0–1 but does not expose those bounds in OpenAPI. Add the same minimum/maximum constraints used by other bounded score responses such as collections/metrics.ts:37-43.

🧠 Review effort: Balanced

Comment thread api/src/lib/overview.ts Outdated

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Signed-off-by: anilb <epipav@gmail.com>
Copilot AI balanced review requested due to automatic review settings October 14, 2026 13:13
@epipav

epipav commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 0f77152. Configure here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The project tuple guard accepts extra slots, allowing malformed upstream tuples to return successfully.

0 open findings

1 resolved since last review
Previously missed (2)

In code that hasn't changed since last review

Medium severity Reject tuples that do not have exactly 13 slots

api/​src/​lib/​oss-index.ts:51

This accepts off-contract tuples longer than the 13-slot TopProjectTuple and silently ignores their tail, so malformed upstream data can return 200 instead of the promised 503. Require the exact tuple length.

Low severity Use singular verb “accepts” for the test subject

api/​tests/​oss-index.test.ts:71

The singular test subject requires “accepts.”

🧠 Review effort: Balanced

@epipav
epipav merged commit 353daf0 into main Oct 14, 2026
13 checks passed
@epipav
epipav deleted the feat/IN-1414 branch October 14, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants